package cn.sowz.test;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.util.List;

public class Demo05 {
    // activiti7 初始化
    @Test
    public void testInit() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine);
    }

    // 流程部署
    @Test
    public void testDeploy(){
        // 启动activiti7流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 部署流程文件-资源操作-RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 加载流程文件+ 流程图片，并实现部署

        // XxxxBuilder 构建者模式，构建对象: Xxxx
        // Deployment --- 部署对象---act_re_deployment
        // DeploymentBuilder builder = repositoryService.createDeployment();
        // builder.addClasspathResource("bpmn/leave.bpmn");
        // builder.addClasspathResource("bpmn/leave.png");
        // builder.name("请假流程");
        // Deployment deploy = builder.deploy();

        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("bpmn/leave.bpmn")
                .addClasspathResource("bpmn/leave.png")
                .name("请假流程")
                .deploy();

        // 输出部署的一些信息
        System.out.println("流程部署ID:"+deploy.getId());
        System.out.println("流程部署名称:"+deploy.getName());
    }

    // 对应业务：A员工发起请假申请
    // 启动实例流程
    @Test
    public void testStartProcess(){
        // 启动activiti7流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 启动流程实例--涉及流程运行/执行--RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();

        // 参数：leaveProcess 是在定义bpmn流程图时候自定的，不同流程图，key不一样
        // 流程实例对象--映射到act_hi_procinst
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveProcess");

        // 获取流程实例的相关信息s
        System.out.println("流程定义的ID:"+instance.getProcessDefinitionId());
        System.out.println("流程实例的ID:"+instance.getId());
    }

    // 对应业务：某个负责人查看自己需要马上审核(任务)操作
    // 查看代办任务
    @Test
    public void testSelectTodoTaskList(){
        // 启动activiti7流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 查看待办任务--涉及任务处理(task)--TaskService
        TaskService taskService = processEngine.getTaskService();

        // A 同学 --- 请假申请----李四审核
        // B 同学 --- 请假申请----李四审核
        // C 同学 --- 报销申请----李四审核
        // D 同学 --- 报销申请----王五审核
        // E 同学 --- 请假申请----王五审核
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("leaveProcess") // 查询条件：流程定义的kev--区分不同审批流程
                .taskAssignee("李四") // 查询条件： 节点（任务）审核人（负责人）
                .list();// List<Task> taskLIst
                // .singleResult(); // Task task

        for (Task task : taskList) {
            System.out.println("流程定义id = " + task.getProcessDefinitionId());
            System.out.println("流程实例id = " + task.getProcessInstanceId());
            System.out.println("任务id = " + task.getId());
            System.out.println("任务名称 = " + task.getName());
        }
    }

    // 对应业务：某个代办任务负责人处理（审核）任务，结果：同意，不同意，根据业务要求执行后续逻辑
    // 任务处理：任务处理之后，流程按照所画流程图的流程执行往后执行（分支操作，需要使用后面学得网关）
    @Test
    public void testCompleteTask(){
        // 启动activiti7流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 处理任务--涉及任务处理(task)--TaskService
        TaskService taskService = processEngine.getTaskService();

        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("leaveProcess") // 查询条件：流程定义的kev--区分不同审批流程
                .taskAssignee("李四") // 查询条件： 节点（任务）审核人（负责人）
                .list();

        // 处理
        for (Task task : taskList) {
            taskService.complete(task.getId());
        }
    }

    @Test
    public void testCompleteTaskAddComment(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("leaveProcess")
                .taskAssignee("张三")
                .list();

        // 处理
        for (Task task : taskList) {
            // 添加处理任务的备注
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"审核通过，同意请假");
            taskService.complete(task.getId());
        }
    }

    // 对应需求：某个任务负责人查看自己审核过的任务信息
    // 查看审核历史(查看已办任务)
    @Test
    public void testSelectHistoryTask(){
        // 启动activiti7流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 查看审核历史---涉及到历史表查询---HistoryService
        HistoryService historyService = processEngine.getHistoryService();

        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .activityType("userTask")  // 查询条件：只查询userTask类型节点
                .processInstanceId("2501") // 查询条件：只查询指定流程id下的历史节点
                .taskAssignee("张三")       // 查询条件：只查询指定负责人的历史节点
                .finished()                   // 查询条件：只查询已经结束历史节点信息
                .list();

        TaskService taskService = processEngine.getTaskService();
        for (HistoricActivityInstance instance : list) {
            System.out.println("任务名称：" + instance.getActivityName());
            System.out.println("任务开始时间：" + instance.getStartTime());
            System.out.println("任务结束时间：" + instance.getEndTime());
            System.out.println("任务耗时：" + instance.getDurationInMillis());
            // 获取审核批注信息
            List<Comment> taskComments = taskService.getTaskComments(instance.getTaskId());
            if (taskComments.size() > 0) {
                System.out.println("审批批注："+taskComments.get(0).getFullMessage());
            }
        }
    }
}
